package com.xyh.transaction.controller;

import com.xyh.transaction.entity.vo.ImgFileVo;
import com.xyh.transaction.response.ResponseResult;
import com.xyh.transaction.utils.CosImageUtil;
import com.xyh.transaction.utils.ImageUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.UUID;

@Api(tags = "文件管理")
@RestController
@RequestMapping("/file")
public class FileController {

    @Value("${image.localDir}")
    private String imageLocalDir;

    @Value("${image.resizeRatio}")
    private Double imageResizeRatio;

    @Value("${image.cosBucketName}")
    private String bucketName;

    @Value("${image.enableLocal}")
    private Boolean enableLocal;

    @Value("${image.localUrl}")
    private String localUrl;

    private final Logger log = LoggerFactory.getLogger(FileController.class);

    @ApiOperation(value = "图片上传", notes = "上传图片文件")
    @PostMapping("/upload/img")
    public ResponseResult<ImgFileVo> uploadImg(
            @ApiParam(value = "图片文件", required = true)
            @RequestParam("file") MultipartFile file) throws Exception {
        String accessFileUrl;

        if (file.isEmpty()) {
            return ResponseResult.failure(HttpStatus.BAD_REQUEST.value(),"上传文件失败！文件为空");
        }
        String fileName = UUID.randomUUID().toString();
        String formatName = getFileExtension(file);

        // 压缩尺寸  好处：节约cos存储空间  弊端：显示不清晰
//        用 ImageIo 的压缩方法
//        MultipartFile resizeImage = ImageUtils.resizeImage(file, fileName, 300, 300);
        // 用 Thumbnails 的压缩方法
//        MultipartFile resizeImage = ImageUtils.resizeImage(file, fileName, formatName, imageResizeRatio);
        // 裁剪图片  好处：显示清晰        弊端：耗费cos存储空间，丢失边缘信息
//        MultipartFile resizeImage = ImageUtils.cropToSquare(file, fileName);

        // 本地存储
        if (enableLocal){
            // 创建存储目录（如果不存在）
            try {
                Files.createDirectories(Paths.get(imageLocalDir));
            } catch (IOException e) {
                log.error("创建存储目录失败: {}", e.getMessage(), e);
                return ResponseResult.failure(HttpStatus.INTERNAL_SERVER_ERROR.value(), "上传文件失败！无法创建存储目录");
            }

            // 生成文件路径
            File dest = new File(imageLocalDir + fileName + "." + formatName);
            log.info("Local file path: " + dest.getAbsolutePath());

            // 压缩图片(本地保存不压缩)
            MultipartFile resizeImage = ImageUtils.resizeImage(file, fileName, formatName, 1);

            // 将文件保存到本地
            resizeImage.transferTo(dest);

            accessFileUrl = localUrl + fileName + "." + formatName;
        }else {

            // 压缩图片
            MultipartFile resizeImage = ImageUtils.resizeImage(file, fileName, formatName, imageResizeRatio);

            // 上传腾讯云
            accessFileUrl = CosImageUtil.uploadImage(bucketName, fileName, formatName, resizeImage);
        }

        // 上传文件并获取访问地址
        return new ResponseResult<>(HttpStatus.OK.value(), "上传成功！", new ImgFileVo(accessFileUrl));
    }

    @ApiOperation(value = "轮播图上传", notes = "上传轮播图文件")
    @PostMapping("/upload/rotate")
    public ResponseResult<ImgFileVo> uploadRotate(
            @RequestParam("file") MultipartFile file) throws Exception {
        String accessFileUrl;

        if (file.isEmpty()) {
            return ResponseResult.failure(HttpStatus.BAD_REQUEST.value(), "上传文件失败！文件为空");
        }
        String fileName = UUID.randomUUID().toString();
        String formatName = getFileExtension(file);

        // 本地存储
        if (enableLocal){
            // 创建存储目录（如果不存在）
            try {
                Files.createDirectories(Paths.get(imageLocalDir));
            } catch (IOException e) {
                log.error("创建存储目录失败: {}", e.getMessage(), e);
                return ResponseResult.failure(HttpStatus.INTERNAL_SERVER_ERROR.value(), "上传文件失败！无法创建存储目录");
            }

            // 生成文件路径
            File dest = new File(imageLocalDir + fileName + "." + formatName);
            log.info("Local file path: " + dest.getAbsolutePath());

            // 压缩图片(本地保存不压缩)
            MultipartFile resizeImage = ImageUtils.resizeImage(file, fileName, formatName);

            // 将文件保存到本地
            resizeImage.transferTo(dest);

            accessFileUrl = localUrl + fileName + "." + formatName;
        }else {

            // 压缩图片
            MultipartFile resizeImage = ImageUtils.resizeImage(file, fileName, formatName, imageResizeRatio);

            // 上传腾讯云
            accessFileUrl = CosImageUtil.uploadImage(bucketName, fileName, formatName, resizeImage);
        }

        // 上传文件并获取访问地址
        return new ResponseResult<>(HttpStatus.OK.value(), "上传成功！", new ImgFileVo(accessFileUrl));
    }

    @ApiOperation(value = "图片下载", notes = "从本地加载图片返回")
    @GetMapping("/download/img/{filename}")
    @ApiImplicitParam(name = "filename", value = "图片名字", required = true)
    public ResponseEntity<byte[]> getImage(@PathVariable String filename) {
        try {
            Path imagePath = Paths.get(imageLocalDir, filename);

            byte[] imageBytes = Files.readAllBytes(imagePath);

            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.IMAGE_JPEG);

            return new ResponseEntity<>(imageBytes, headers, HttpStatus.OK);
        } catch (IOException e) {
            log.error("Exception during image retrieval: {}", e.getMessage(), e);
            return new ResponseEntity<>(HttpStatus.NOT_FOUND);
        }
    }

    private String getFileExtension(MultipartFile file) {
        String fileName = file.getOriginalFilename();
        if (fileName == null) {
            return "png";
        }
        file.getOriginalFilename();
        int dotIndex = fileName.lastIndexOf('.');
        return (dotIndex == -1) ? "" : fileName.substring(dotIndex+1);
    }
}
